package AnalisadorSintatico;

import AnalisadorLexico.CodigoErros;
import TabelaDeSimbolos.nodoEncadeado;
import static TabelaDeSimbolos.classeTabelaSimbolos.tabelaSimbolos;
import AnalisadorLexico.Lexico;
import AnalisadorSemantico.ClassesSemanticas;
import AnalisadorSemantico.TiposSemanticos;
import com.sun.swing.internal.plaf.metal.resources.metal;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

// ANALISADOR SINTATICO
public class Sintatico {
    File arquivo;
    FileOutputStream geraASM;

    public Lexico lexico;
    public nodoEncadeado nodoRegistrado;
    public nodoEncadeado nodoAuxiliar;
    public nodoEncadeado nodoConstAuxiliar;
    public nodoEncadeado nodoExpressaoTemp;
    public nodoEncadeado nodoFatorTemp;
    public nodoEncadeado nodoVarTemp;
    public PalavrasReservadas pr;
    public ArrayList<String> escopoDPonto;
    public ArrayList<String> escopoDFace;
    public ArrayList<String> escopoDCor;
    public ArrayList<String> escopoDLuz;
    public ArrayList<String> escopoDObjeto;
    public ArrayList<String> escopoDConst;
    public ArrayList<String> escopoDVar;
    public boolean isInteiro;
    // Declaração prévia de variáveis (erro às atribuições certas)
    boolean tipo = false;

    public Sintatico(Lexico lexico) throws IOException {
        this.lexico = lexico;
        nodoAuxiliar = new nodoEncadeado((byte) 0, "");
        nodoConstAuxiliar = new nodoEncadeado((byte) 0, "");
        nodoFatorTemp = new nodoEncadeado((byte) 0, TiposSemanticos.Inteiro.getTipo());
        nodoVarTemp = new nodoEncadeado((byte) 0, TiposSemanticos.Inteiro.getTipo());
        arquivo = new File("codigoGerado.asm");
        geraASM = new FileOutputStream(arquivo);
        
        //geraASM.write("texto".getBytes()); // Escreve no arquivo
        //geraASM.close(); // Fecha o arquivo

        escopoDPonto = new ArrayList<String>();
        escopoDFace = new ArrayList<String>();
        escopoDCor = new ArrayList<String>();
        escopoDLuz = new ArrayList<String>();
        escopoDObjeto = new ArrayList<String>();
        escopoDConst = new ArrayList<String>();
        escopoDVar = new ArrayList<String>();

        nodoRegistrado = lexico.AnalisaLexico();
        while (nodoRegistrado.getToken() == -1 || nodoRegistrado.getToken() == 46) {
            nodoRegistrado = lexico.AnalisaLexico();
        }
        MetodoS();
    }

    void CasaToken(byte tok_esperado) throws IOException {
        if (tok_esperado == nodoRegistrado.getToken() && nodoRegistrado.getToken() != -3) {
            nodoRegistrado = lexico.AnalisaLexico();


        } else {
            //    lexico.mensagemErro(AnalisadorLexico.CodigoErros.tokenNaoEsperado.getCodigoErro());
            lexico.mensagemErro(CodigoErros.tokenNaoEsperado.getCodigoErro(), nodoRegistrado.getLexema());
        }
    }

    private void MetodoS() throws IOException {
        while (nodoRegistrado.getToken() == pr.prDPonto.getPr() || nodoRegistrado.getToken() == pr.prDLuz.getPr()
                || nodoRegistrado.getToken() == pr.prDCor.getPr() || nodoRegistrado.getToken() == pr.prDFace.getPr()
                || nodoRegistrado.getToken() == pr.prDObjeto.getPr() || nodoRegistrado.getToken() == pr.prDVar.getPr()
                || nodoRegistrado.getToken() == pr.prDConst.getPr()) {
            MetodoD();

        }
        MetodoB();
        //  MetodoT();
    }

    void MetodoD() throws IOException {
        if (nodoRegistrado.getToken() == pr.prDPonto.getPr()) {
            CasaToken(pr.prDPonto.getPr()); //int
            CasaToken(pr.prQuebra.getPr());

            while (nodoRegistrado.getToken() == pr.prID.getPr()) {
                nodoAuxiliar = lexico.metodo.pesquisa(nodoRegistrado.getLexema().toLowerCase());


                nodoAuxiliar.setClasse(ClassesSemanticas.DPonto.getClasse());
                nodoAuxiliar.setTipo(TiposSemanticos.Ponto.getTipo());

                lexico.metodo.defineClasse(nodoAuxiliar);
                lexico.metodo.defineTipo(nodoAuxiliar);

                if (!escopoDPonto.contains(nodoAuxiliar.getLexema().toLowerCase())) {
                    escopoDPonto.add(nodoRegistrado.getLexema().toLowerCase());
                    CasaToken(pr.prID.getPr());

                } else {
                    lexico.mensagemErro(CodigoErros.identificadorJaDeclarado.getCodigoErro(), nodoAuxiliar.getLexema());
                }


                CasaToken(pr.prAttribEqual.getPr());

                CasaToken(pr.prOpar.getPr());

                if (nodoRegistrado.getToken() == pr.prMinus.getPr()) {
                    CasaToken(pr.prMinus.getPr());
                }

                nodoAuxiliar = lexico.metodo.pesquisa(nodoRegistrado.getLexema().toLowerCase());
                nodoAuxiliar = lexico.metodo.verificaTipo(nodoAuxiliar);
                if (nodoAuxiliar.getTipo().equals(TiposSemanticos.Inteiro.getTipo())) {
                    CasaToken(pr.prConst.getPr());
                } else {
                    lexico.mensagemErro(CodigoErros.tiposIncompativeis.getCodigoErro(), nodoAuxiliar.getLexema());
                }

                CasaToken(pr.prComma.getPr());
                if (nodoRegistrado.getToken() == pr.prMinus.getPr()) {
                    CasaToken(pr.prMinus.getPr());
                }
                nodoAuxiliar = lexico.metodo.pesquisa(nodoRegistrado.getLexema().toLowerCase());
                if (nodoAuxiliar.getTipo().equals(TiposSemanticos.Inteiro.getTipo())) {
                    CasaToken(pr.prConst.getPr());
                } else {
                    lexico.mensagemErro(CodigoErros.tiposIncompativeis.getCodigoErro(), nodoAuxiliar.getLexema());
                }
                CasaToken(pr.prComma.getPr());

                if (nodoRegistrado.getToken() == pr.prMinus.getPr()) {
                    CasaToken(pr.prMinus.getPr());
                }

                nodoAuxiliar = lexico.metodo.pesquisa(nodoRegistrado.getLexema().toLowerCase());
                if (nodoAuxiliar.getTipo().equals(TiposSemanticos.Inteiro.getTipo())) {
                    CasaToken(pr.prConst.getPr());
                } else {
                    lexico.mensagemErro(CodigoErros.tiposIncompativeis.getCodigoErro(), nodoAuxiliar.getLexema());
                }
                CasaToken(pr.prCpar.getPr());

                CasaToken(pr.prQuebra.getPr());
            }

        } else if (nodoRegistrado.getToken() == pr.prDLuz.getPr()) {
            CasaToken(pr.prDLuz.getPr()); //int
            CasaToken(pr.prQuebra.getPr());

            while (nodoRegistrado.getToken() == pr.prID.getPr()) {

                nodoAuxiliar = lexico.metodo.pesquisa(nodoRegistrado.getLexema().toLowerCase());

                nodoAuxiliar.setClasse(ClassesSemanticas.DLuz.getClasse());
                nodoAuxiliar.setTipo(TiposSemanticos.Luz.getTipo());

                lexico.metodo.defineClasse(nodoAuxiliar);
                lexico.metodo.defineTipo(nodoAuxiliar);



                if (!escopoDLuz.contains(nodoAuxiliar.getLexema().toLowerCase())) {
                    escopoDLuz.add(nodoRegistrado.getLexema().toLowerCase());
                    CasaToken(pr.prID.getPr());

                } else {
                    lexico.mensagemErro(CodigoErros.identificadorJaDeclarado.getCodigoErro(), nodoAuxiliar.getLexema());
                }

                CasaToken(pr.prAttribEqual.getPr());

                CasaToken(pr.prOpar.getPr());

                if (nodoRegistrado.getToken() == pr.prMinus.getPr()) {
                    CasaToken(pr.prMinus.getPr());
                }
                CasaToken(pr.prConst.getPr());
                CasaToken(pr.prComma.getPr());
                if (nodoRegistrado.getToken() == pr.prMinus.getPr()) {
                    
                    //TODO REMOVER E ATLERAR E FAZER FUNCIONAR
                    lexico.metodo.tks.add(nodoAuxiliar.getLexema());
                    
                    CasaToken(pr.prMinus.getPr());
                }
                CasaToken(pr.prConst.getPr());
                CasaToken(pr.prComma.getPr());
                if (nodoRegistrado.getToken() == pr.prMinus.getPr()) {
                    CasaToken(pr.prMinus.getPr());
                }
                CasaToken(pr.prConst.getPr());

                CasaToken(pr.prCpar.getPr());

                CasaToken(pr.prQuebra.getPr());
            }


        } else if (nodoRegistrado.getToken() == pr.prDCor.getPr()) {
            CasaToken(pr.prDCor.getPr()); //Cor
            CasaToken(pr.prQuebra.getPr());

            while (nodoRegistrado.getToken() == pr.prID.getPr()) {


                nodoAuxiliar = lexico.metodo.pesquisa(nodoRegistrado.getLexema().toLowerCase());

                nodoAuxiliar.setClasse(ClassesSemanticas.DCor.getClasse());
                nodoAuxiliar.setTipo(TiposSemanticos.Cor.getTipo());

                lexico.metodo.defineClasse(nodoAuxiliar);
                lexico.metodo.defineTipo(nodoAuxiliar);

                if (!escopoDCor.contains(nodoAuxiliar.getLexema().toLowerCase())) {
                    escopoDCor.add(nodoRegistrado.getLexema().toLowerCase());
                    CasaToken(pr.prID.getPr());

                } else {
                    lexico.mensagemErro(CodigoErros.identificadorJaDeclarado.getCodigoErro(), nodoAuxiliar.getLexema());
                }
                CasaToken(pr.prAttribEqual.getPr());

                if (nodoRegistrado.getToken() == pr.prMinus.getPr()) {
                    CasaToken(pr.prMinus.getPr());
                }

                CasaToken(pr.prConst.getPr());
                CasaToken(pr.prComma.getPr());

                if (nodoRegistrado.getToken() == pr.prMinus.getPr()) {
                    CasaToken(pr.prMinus.getPr());
                }
                CasaToken(pr.prConst.getPr());
                CasaToken(pr.prComma.getPr());

                if (nodoRegistrado.getToken() == pr.prMinus.getPr()) {
                    CasaToken(pr.prMinus.getPr());
                }
                CasaToken(pr.prConst.getPr());
                CasaToken(pr.prComma.getPr());

                if (nodoRegistrado.getToken() == pr.prMinus.getPr()) {
                    CasaToken(pr.prMinus.getPr());
                }
                CasaToken(pr.prConst.getPr());
                CasaToken(pr.prComma.getPr());

                if (nodoRegistrado.getToken() == pr.prMinus.getPr()) {
                    CasaToken(pr.prMinus.getPr());
                }
                CasaToken(pr.prConst.getPr());
                CasaToken(pr.prComma.getPr());

                if (nodoRegistrado.getToken() == pr.prMinus.getPr()) {
                    CasaToken(pr.prMinus.getPr());
                }
                CasaToken(pr.prConst.getPr());
                CasaToken(pr.prComma.getPr());

                if (nodoRegistrado.getToken() == pr.prMinus.getPr()) {
                    CasaToken(pr.prMinus.getPr());
                }
                CasaToken(pr.prConst.getPr());


                CasaToken(pr.prQuebra.getPr());
            }


        } else if (nodoRegistrado.getToken() == pr.prDFace.getPr()) {
            CasaToken(pr.prDFace.getPr()); //Face
            CasaToken(pr.prQuebra.getPr());

            while (nodoRegistrado.getToken() == pr.prID.getPr()) {

                nodoAuxiliar = lexico.metodo.pesquisa(nodoRegistrado.getLexema().toLowerCase());

                nodoAuxiliar.setClasse(ClassesSemanticas.DFace.getClasse());

                nodoAuxiliar.setTipo(TiposSemanticos.Face.getTipo());

                lexico.metodo.defineClasse(nodoAuxiliar);
                lexico.metodo.defineTipo(nodoAuxiliar);

                if (!escopoDFace.contains(nodoAuxiliar.getLexema().toLowerCase())) {
                    escopoDFace.add(nodoRegistrado.getLexema().toLowerCase());
                    CasaToken(pr.prID.getPr());

                } else {
                    lexico.mensagemErro(CodigoErros.identificadorJaDeclarado.getCodigoErro(), nodoAuxiliar.getLexema());
                }

                CasaToken(pr.prAttribEqual.getPr());

                //ACAO SEMANTICA REFERENTE AO ID ABAIXO
                nodoAuxiliar = lexico.metodo.pesquisa(nodoRegistrado.getLexema().toLowerCase());

                if (!nodoAuxiliar.getClasse().equals(ClassesSemanticas.DCor.getClasse())) {
                    lexico.mensagemErro(CodigoErros.classeIncompativel.getCodigoErro(), nodoAuxiliar.getLexema());
                }
                if (!nodoAuxiliar.getTipo().equals(TiposSemanticos.Cor.getTipo())) {
                    lexico.mensagemErro(CodigoErros.tiposIncompativeis.getCodigoErro(), nodoAuxiliar.getLexema());
                }

                if (!escopoDCor.contains(nodoAuxiliar.getLexema().toLowerCase())) {
                    lexico.mensagemErro(CodigoErros.identificadorNaoDeclarado.getCodigoErro(), nodoAuxiliar.getLexema());
                }

                //FIM ACAO SEMANTICA

                CasaToken(pr.prID.getPr());




                CasaToken(pr.prComma.getPr());

                //ACAO SEMANTICA REFERENTE AO ID ABAIXO
                nodoAuxiliar = lexico.metodo.pesquisa(nodoRegistrado.getLexema().toLowerCase());

                if (!nodoAuxiliar.getClasse().equals(ClassesSemanticas.DPonto.getClasse())) {
                    lexico.mensagemErro(CodigoErros.classeIncompativel.getCodigoErro(), nodoAuxiliar.getLexema());
                }
                if (!nodoAuxiliar.getTipo().equals(TiposSemanticos.Ponto.getTipo())) {
                    lexico.mensagemErro(CodigoErros.tiposIncompativeis.getCodigoErro(), nodoAuxiliar.getLexema());
                }
                if (!escopoDPonto.contains(nodoAuxiliar.getLexema().toLowerCase())) {
                    lexico.mensagemErro(CodigoErros.identificadorNaoDeclarado.getCodigoErro(), nodoAuxiliar.getLexema());
                }


                //FIM ACAO SEMANTICA


                CasaToken(pr.prID.getPr());




                CasaToken(pr.prComma.getPr());

                //ACAO SEMANTICA REFERENTE AO ID ABAIXO
                nodoAuxiliar = lexico.metodo.pesquisa(nodoRegistrado.getLexema().toLowerCase());

                if (!nodoAuxiliar.getClasse().equals(ClassesSemanticas.DPonto.getClasse())) {
                    lexico.mensagemErro(CodigoErros.classeIncompativel.getCodigoErro(), nodoAuxiliar.getLexema());
                }
                if (!nodoAuxiliar.getTipo().equals(TiposSemanticos.Ponto.getTipo())) {
                    lexico.mensagemErro(CodigoErros.tiposIncompativeis.getCodigoErro(), nodoAuxiliar.getLexema());
                }
                if (!escopoDPonto.contains(nodoAuxiliar.getLexema().toLowerCase())) {
                    lexico.mensagemErro(CodigoErros.identificadorNaoDeclarado.getCodigoErro(), nodoAuxiliar.getLexema());
                }


                //FIM ACAO SEMANTICA


                CasaToken(pr.prID.getPr());




                CasaToken(pr.prComma.getPr());

                //ACAO SEMANTICA REFERENTE AO ID ABAIXO
                nodoAuxiliar = lexico.metodo.pesquisa(nodoRegistrado.getLexema().toLowerCase());

                if (!nodoAuxiliar.getClasse().equals(ClassesSemanticas.DPonto.getClasse())) {
                    lexico.mensagemErro(CodigoErros.classeIncompativel.getCodigoErro(), nodoAuxiliar.getLexema());
                }
                if (!nodoAuxiliar.getTipo().equals(TiposSemanticos.Ponto.getTipo())) {
                    lexico.mensagemErro(CodigoErros.tiposIncompativeis.getCodigoErro(), nodoAuxiliar.getLexema());
                }
                if (!escopoDPonto.contains(nodoAuxiliar.getLexema().toLowerCase())) {
                    lexico.mensagemErro(CodigoErros.identificadorNaoDeclarado.getCodigoErro(), nodoAuxiliar.getLexema());
                }

                //FIM ACAO SEMANTICA



                CasaToken(pr.prID.getPr());





                while (nodoRegistrado.getToken() == pr.prComma.getPr()) {
                    CasaToken(pr.prComma.getPr());

                    //ACAO SEMANTICA REFERENTE AO ID ABAIXO
                    nodoAuxiliar = lexico.metodo.pesquisa(nodoRegistrado.getLexema().toLowerCase());

                    if (!nodoAuxiliar.getClasse().equals(ClassesSemanticas.DPonto.getClasse())) {
                        lexico.mensagemErro(CodigoErros.classeIncompativel.getCodigoErro(), nodoAuxiliar.getLexema());
                    }
                    if (!nodoAuxiliar.getTipo().equals(TiposSemanticos.Ponto.getTipo())) {
                        lexico.mensagemErro(CodigoErros.tiposIncompativeis.getCodigoErro(), nodoAuxiliar.getLexema());
                    }
                    if (!escopoDPonto.contains(nodoAuxiliar.getLexema().toLowerCase())) {
                        lexico.mensagemErro(CodigoErros.identificadorNaoDeclarado.getCodigoErro(), nodoAuxiliar.getLexema());
                    }

                    //FIM ACAO SEMANTICA



                    CasaToken(pr.prID.getPr());




                }


                CasaToken(pr.prQuebra.getPr());
            }


        } else if (nodoRegistrado.getToken() == pr.prDObjeto.getPr()) {
            CasaToken(pr.prDObjeto.getPr());
            CasaToken(pr.prQuebra.getPr());

            while (nodoRegistrado.getToken() == pr.prID.getPr()) {

                nodoAuxiliar = lexico.metodo.pesquisa(nodoRegistrado.getLexema().toLowerCase());

                nodoAuxiliar.setClasse(ClassesSemanticas.DObjeto.getClasse());
                nodoAuxiliar.setTipo(TiposSemanticos.Objeto.getTipo());

                lexico.metodo.defineClasse(nodoAuxiliar);
                lexico.metodo.defineTipo(nodoAuxiliar);




                if (!escopoDObjeto.contains(nodoAuxiliar.getLexema().toLowerCase())) {
                    escopoDObjeto.add(nodoRegistrado.getLexema().toLowerCase());
                    CasaToken(pr.prID.getPr());

                } else {
                    lexico.mensagemErro(CodigoErros.identificadorJaDeclarado.getCodigoErro(), nodoAuxiliar.getLexema());
                }




                CasaToken(pr.prAttribEqual.getPr());

                nodoAuxiliar = lexico.metodo.pesquisa(nodoRegistrado.getLexema().toLowerCase());



                if (!escopoDFace.contains(nodoAuxiliar.getLexema().toLowerCase())) {
                    lexico.mensagemErro(CodigoErros.identificadorNaoDeclarado.getCodigoErro(), nodoAuxiliar.getLexema());
                }

                CasaToken(pr.prID.getPr());



                while (nodoRegistrado.getToken() == pr.prComma.getPr()) {

                    CasaToken(pr.prComma.getPr());

                    nodoAuxiliar = lexico.metodo.pesquisa(nodoRegistrado.getLexema().toLowerCase());


                    if (!escopoDFace.contains(nodoAuxiliar.getLexema().toLowerCase())) {
                        lexico.mensagemErro(CodigoErros.identificadorNaoDeclarado.getCodigoErro(), nodoAuxiliar.getLexema());
                    }
                    CasaToken(pr.prID.getPr());


                }

                CasaToken(pr.prQuebra.getPr());
            }


        } else if (nodoRegistrado.getToken() == pr.prDVar.getPr()) {
            CasaToken(pr.prDVar.getPr()); //Face
            CasaToken(pr.prQuebra.getPr());

            while (nodoRegistrado.getToken() == pr.prInteiro.getPr()
                    || nodoRegistrado.getToken() == pr.prReal.getPr()) {



                if (nodoRegistrado.getToken() == pr.prInteiro.getPr()) {
                    //colocar nodo auxiliar e definir classe e tipo  FEITO

                    nodoVarTemp.setTipo(TiposSemanticos.Inteiro.getTipo());
                    lexico.metodo.defineTipo(nodoVarTemp);
                    CasaToken(pr.prInteiro.getPr());



                    nodoAuxiliar = lexico.metodo.pesquisa(nodoRegistrado.getLexema().toLowerCase());
                    nodoAuxiliar.setClasse(ClassesSemanticas.DVar.getClasse());
                    nodoAuxiliar.setTipo(TiposSemanticos.Inteiro.getTipo());

                    lexico.metodo.defineClasse(nodoAuxiliar);
                    lexico.metodo.defineTipo(nodoAuxiliar);

                } else {
                    //colocar nodo auxiliar e definir classe e tipo FEITO
                    nodoVarTemp.setTipo(TiposSemanticos.Real.getTipo());
                    lexico.metodo.defineTipo(nodoVarTemp);

                    CasaToken(pr.prReal.getPr());
                    nodoAuxiliar = lexico.metodo.pesquisa(nodoRegistrado.getLexema().toLowerCase());
                    nodoAuxiliar.setClasse(ClassesSemanticas.DVar.getClasse());
                    nodoAuxiliar.setTipo(TiposSemanticos.Real.getTipo());

                    lexico.metodo.defineClasse(nodoAuxiliar);
                    lexico.metodo.defineTipo(nodoAuxiliar);
                }





                if (!escopoDVar.contains(nodoAuxiliar.getLexema().toLowerCase())) {
                    escopoDVar.add(nodoAuxiliar.getLexema().toLowerCase());
                    CasaToken(pr.prID.getPr());
                } else {
                    lexico.mensagemErro(CodigoErros.identificadorJaDeclarado.getCodigoErro(), nodoAuxiliar.getLexema());
                }

                // CasaToken(pr.prQuebra.getPr());

                while (nodoRegistrado.getToken() == pr.prComma.getPr()) {
                    CasaToken(pr.prComma.getPr());

                    nodoAuxiliar = lexico.metodo.pesquisa(nodoRegistrado.getLexema().toLowerCase());

                    if (nodoVarTemp.getTipo().equals(TiposSemanticos.Inteiro.getTipo())) {
                        //colocar nodo auxiliar e definir classe e tipo  FEITO


                        nodoAuxiliar = lexico.metodo.pesquisa(nodoRegistrado.getLexema().toLowerCase());
                        nodoAuxiliar.setClasse(ClassesSemanticas.DVar.getClasse());
                        nodoAuxiliar.setTipo(TiposSemanticos.Inteiro.getTipo());

                        lexico.metodo.defineClasse(nodoAuxiliar);
                        lexico.metodo.defineTipo(nodoAuxiliar);

                    } else if (nodoVarTemp.getTipo().equals(TiposSemanticos.Real.getTipo())) {
                        //colocar nodo auxiliar e definir classe e tipo FEITO


                        nodoAuxiliar = lexico.metodo.pesquisa(nodoRegistrado.getLexema().toLowerCase());
                        nodoAuxiliar.setClasse(ClassesSemanticas.DVar.getClasse());
                        nodoAuxiliar.setTipo(TiposSemanticos.Real.getTipo());

                        lexico.metodo.defineClasse(nodoAuxiliar);
                        lexico.metodo.defineTipo(nodoAuxiliar);
                    }



                    if (!escopoDVar.contains(nodoAuxiliar.getLexema().toLowerCase())) {
                        escopoDVar.add(nodoAuxiliar.getLexema().toLowerCase());
                        CasaToken(pr.prID.getPr());
                    } else {
                        lexico.mensagemErro(CodigoErros.identificadorJaDeclarado.getCodigoErro(), nodoAuxiliar.getLexema());
                    }
                }

                CasaToken(pr.prQuebra.getPr());
            }
        } else {
            CasaToken(pr.prDConst.getPr()); //Const
            CasaToken(pr.prQuebra.getPr());

            while (nodoRegistrado.getToken() == pr.prID.getPr()) {

                //colocar nodo auxiliar e definir classe e tipo

                nodoConstAuxiliar = lexico.metodo.pesquisa(nodoRegistrado.getLexema().toLowerCase());

                nodoConstAuxiliar.setClasse(ClassesSemanticas.DConst.getClasse());

                lexico.metodo.defineClasse(nodoConstAuxiliar);


                if (!escopoDConst.contains(nodoConstAuxiliar.getLexema().toLowerCase())) {
                    escopoDConst.add(nodoConstAuxiliar.getLexema().toLowerCase());
                    CasaToken(pr.prID.getPr());
                } else {
                    lexico.mensagemErro(CodigoErros.identificadorJaDeclarado.getCodigoErro(), nodoConstAuxiliar.getLexema());
                }

                nodoAuxiliar = lexico.metodo.pesquisa(nodoRegistrado.getLexema().toLowerCase());

                CasaToken(pr.prAttribEqual.getPr());

                if (nodoRegistrado.getToken() == pr.prPlus.getPr()) {
                    CasaToken(pr.prPlus.getPr());
                } else if (nodoRegistrado.getToken() == pr.prMinus.getPr()) {
                    CasaToken(pr.prMinus.getPr());
                }
                nodoAuxiliar = lexico.metodo.pesquisa(nodoRegistrado.getLexema().toLowerCase());

                if (lexico.metodo.verificaTipo(nodoAuxiliar).getTipo().equals(TiposSemanticos.Real.getTipo())) {
                    nodoConstAuxiliar.setTipo(TiposSemanticos.Real.getTipo());
                } else {
                    nodoConstAuxiliar.setTipo(TiposSemanticos.Inteiro.getTipo());
                }


                lexico.metodo.defineTipo(nodoConstAuxiliar);

                CasaToken(pr.prConst.getPr());

                CasaToken(pr.prQuebra.getPr());
            }
        }
    }

    //FIM METODO D
    void MetodoB() throws IOException {


        while (nodoRegistrado.getToken() == pr.prQuebra.getPr()) {
            CasaToken(pr.prQuebra.getPr());
        }

        if (nodoRegistrado.getToken() == pr.prBegin.getPr()) {
            CasaToken(pr.prBegin.getPr());
            CasaToken(pr.prQuebra.getPr());
            MetodoL();
            CasaToken(pr.prEnd.getPr());
            if (nodoRegistrado.getToken() != pr.prEnd.getPr()) {
                CasaToken(pr.prQuebra.getPr());
            } else {
                //  System.out.println("METODO B: ELE FOI INTELGIENTE E PAROU");
            }
        }




    }

    void MetodoL() throws IOException {

        while (nodoRegistrado.getToken() == pr.prID.getPr()
                || nodoRegistrado.getToken() == pr.prEnquanto.getPr()
                || nodoRegistrado.getToken() == pr.prSe.getPr()
                || nodoRegistrado.getToken() == pr.prEscala.getPr()
                || nodoRegistrado.getToken() == pr.prPausa.getPr()
                || nodoRegistrado.getToken() == pr.prLuz.getPr()
                || nodoRegistrado.getToken() == pr.prRotTrans.getPr()
                || nodoRegistrado.getToken() == pr.prQuebra.getPr()) {
            if (nodoRegistrado.getToken() == pr.prID.getPr()) {
                MetodoA();
            } else if (nodoRegistrado.getToken() == pr.prEnquanto.getPr()) {
                MetodoR();
            } else if (nodoRegistrado.getToken() == pr.prSe.getPr()) {
                MetodoT();
            } else if (nodoRegistrado.getToken() == pr.prEscala.getPr()) {
                MetodoESC();
            } else if (nodoRegistrado.getToken() == pr.prPausa.getPr()) {
                MetodoP();
            } else if (nodoRegistrado.getToken() == pr.prLuz.getPr()) {
                MetodoLUZ();
            } else if (nodoRegistrado.getToken() == pr.prRotTrans.getPr()) {
                MetodoROT();
            } else {
                CasaToken(pr.prQuebra.getPr());
            }

        }



    }

    void MetodoA() throws IOException {

        nodoExpressaoTemp = lexico.metodo.pesquisa(nodoRegistrado.getLexema().toLowerCase());

        if (!escopoDVar.contains(nodoExpressaoTemp.getLexema().toLowerCase())) {
            lexico.mensagemErro(CodigoErros.identificadorNaoDeclarado.getCodigoErro(), nodoExpressaoTemp.getLexema());

        } else {
            CasaToken(pr.prID.getPr());

        }


        CasaToken(pr.prAttribEqual.getPr());

        MetodoEXP();

        if (!nodoExpressaoTemp.getTipo().equals(nodoFatorTemp.getTipo())) {
            lexico.mensagemErro(CodigoErros.tiposIncompativeis.getCodigoErro(), nodoExpressaoTemp.getLexema());
        }
        CasaToken(pr.prQuebra.getPr());
    }

    void MetodoR() throws IOException {
        CasaToken(pr.prEnquanto.getPr());
        MetodoEXP();

        CasaToken(pr.prFaca.getPr());


        //  CasaToken(pr.prQuebra.getPr());
        MetodoB();
        //talvez role de por um END do bloco aqui porque ta osso
    }

    void MetodoT() throws IOException {
        CasaToken(pr.prSe.getPr());
        MetodoEXP();
        CasaToken(pr.prEntao.getPr());

        
        CasaToken(pr.prQuebra.getPr());
        
        if (nodoRegistrado.getToken() == pr.prBegin.getPr()) {
            MetodoB();

        } else {
            MetodoL();
        }

        if (nodoRegistrado.getToken() == pr.prSenao.getPr()) {
            CasaToken(pr.prSenao.getPr());
            CasaToken(pr.prQuebra.getPr());
            if (nodoRegistrado.getToken() == pr.prBegin.getPr()) {
                MetodoB();
            } else {
                MetodoL();
            }
        }
    }

    void MetodoESC() throws IOException {
        CasaToken(pr.prEscala.getPr());

        nodoAuxiliar = lexico.metodo.pesquisa(nodoRegistrado.getLexema().toLowerCase());

        nodoAuxiliar.setClasse(ClassesSemanticas.DObjeto.getClasse());
        nodoAuxiliar.setTipo(TiposSemanticos.Objeto.getTipo());

        lexico.metodo.defineClasse(nodoAuxiliar);
        lexico.metodo.defineTipo(nodoAuxiliar);


        if (!escopoDObjeto.contains(nodoAuxiliar.getLexema().toLowerCase())) {
            lexico.mensagemErro(CodigoErros.identificadorNaoDeclarado.getCodigoErro(), nodoAuxiliar.getLexema());


        } else {
            CasaToken(pr.prID.getPr());
        }
        CasaToken(pr.prComma.getPr());
        MetodoEXP();
        if (!(nodoFatorTemp.getTipo().equals(TiposSemanticos.Real.getTipo())
                || nodoFatorTemp.getTipo().equals(TiposSemanticos.Inteiro.getTipo()))) {
            lexico.mensagemErro(CodigoErros.tiposIncompativeis.getCodigoErro(), nodoFatorTemp.getLexema());
        }

        CasaToken(pr.prQuebra.getPr());
    }

    void MetodoP() throws IOException {
        CasaToken(pr.prPausa.getPr());
        MetodoEXP();
        if (!(nodoFatorTemp.getTipo().equals(TiposSemanticos.Inteiro.getTipo())
                || nodoFatorTemp.getTipo().equals(TiposSemanticos.Real.getTipo()))) {
            lexico.mensagemErro(CodigoErros.tiposIncompativeis.getCodigoErro(), nodoFatorTemp.getLexema());
        }

        CasaToken(pr.prQuebra.getPr());
    }

    void MetodoLUZ() throws IOException {
        CasaToken(pr.prLuz.getPr());

        nodoAuxiliar = lexico.metodo.pesquisa(nodoRegistrado.getLexema().toLowerCase());

        nodoAuxiliar.setClasse(ClassesSemanticas.DLuz.getClasse());
        nodoAuxiliar.setTipo(TiposSemanticos.Luz.getTipo());

        lexico.metodo.defineClasse(nodoAuxiliar);
        lexico.metodo.defineTipo(nodoAuxiliar);


        if (!escopoDLuz.contains(nodoAuxiliar.getLexema().toLowerCase())) {
            lexico.mensagemErro(CodigoErros.identificadorNaoDeclarado.getCodigoErro(), nodoAuxiliar.getLexema());


        } else {

            CasaToken(pr.prID.getPr());
        }

        CasaToken(pr.prQuebra.getPr());
    }

    void MetodoROT() throws IOException {
        CasaToken(pr.prRotTrans.getPr());
        CasaToken(pr.prID.getPr());

        CasaToken(pr.prComma.getPr());
        MetodoEXP();
        if (!(nodoFatorTemp.getTipo().equals(TiposSemanticos.Inteiro.getTipo())
                || nodoFatorTemp.getTipo().equals(TiposSemanticos.Real.getTipo()))) {
            lexico.mensagemErro(CodigoErros.tiposIncompativeis.getCodigoErro(), nodoFatorTemp.getLexema());
        }
        CasaToken(pr.prComma.getPr());
        MetodoEXP();
        if (!(nodoFatorTemp.getTipo().equals(TiposSemanticos.Inteiro.getTipo())
                || nodoFatorTemp.getTipo().equals(TiposSemanticos.Real.getTipo()))) {
            lexico.mensagemErro(CodigoErros.tiposIncompativeis.getCodigoErro(), nodoFatorTemp.getLexema());
        }
        CasaToken(pr.prComma.getPr());
        MetodoEXP();
        if (!(nodoFatorTemp.getTipo().equals(TiposSemanticos.Inteiro.getTipo())
                || nodoFatorTemp.getTipo().equals(TiposSemanticos.Real.getTipo()))) {
            lexico.mensagemErro(CodigoErros.tiposIncompativeis.getCodigoErro(), nodoFatorTemp.getLexema());
        }
        CasaToken(pr.prComma.getPr());
        MetodoEXP();
        if (!(nodoFatorTemp.getTipo().equals(TiposSemanticos.Inteiro.getTipo())
                || nodoFatorTemp.getTipo().equals(TiposSemanticos.Real.getTipo()))) {
            lexico.mensagemErro(CodigoErros.tiposIncompativeis.getCodigoErro(), nodoFatorTemp.getLexema());
        }
        CasaToken(pr.prComma.getPr());
        MetodoEXP();
        if (!(nodoFatorTemp.getTipo().equals(TiposSemanticos.Inteiro.getTipo())
                || nodoFatorTemp.getTipo().equals(TiposSemanticos.Real.getTipo()))) {
            lexico.mensagemErro(CodigoErros.tiposIncompativeis.getCodigoErro(), nodoFatorTemp.getLexema());
        }
        CasaToken(pr.prComma.getPr());
        MetodoEXP();
        if (!(nodoFatorTemp.getTipo().equals(TiposSemanticos.Inteiro.getTipo())
                || nodoFatorTemp.getTipo().equals(TiposSemanticos.Real.getTipo()))) {
            lexico.mensagemErro(CodigoErros.tiposIncompativeis.getCodigoErro(), nodoFatorTemp.getLexema());
        }

        CasaToken(pr.prQuebra.getPr());
    }

    void MetodoEXP() throws IOException {
        MetodoEXPS();
        if (nodoRegistrado.getToken() == pr.prLessThan.getPr()
                || nodoRegistrado.getToken() == pr.prLessOrEqual.getPr()
                || nodoRegistrado.getToken() == pr.prGreaterThan.getPr()
                || nodoRegistrado.getToken() == pr.prGreaterOrEqual.getPr()
                || nodoRegistrado.getToken() == pr.prIfEquals.getPr()
                || nodoRegistrado.getToken() == pr.prDifferent.getPr()) {

            if (nodoRegistrado.getToken() == pr.prLessThan.getPr()) {
                CasaToken(pr.prLessThan.getPr());
            }
            if (nodoRegistrado.getToken() == pr.prLessOrEqual.getPr()) {
                CasaToken(pr.prLessOrEqual.getPr());
            }
            if (nodoRegistrado.getToken() == pr.prGreaterThan.getPr()) {
                CasaToken(pr.prGreaterThan.getPr());
            }
            if (nodoRegistrado.getToken() == pr.prGreaterOrEqual.getPr()) {
                CasaToken(pr.prGreaterOrEqual.getPr());
            }
            if (nodoRegistrado.getToken() == pr.prIfEquals.getPr()) {
                CasaToken(pr.prIfEquals.getPr());
            }

            if (nodoRegistrado.getToken() == pr.prDifferent.getPr()) {
                CasaToken(pr.prDifferent.getPr());
            }
            MetodoEXPS();
        }
    }

    void MetodoEXPS() throws IOException {
        if (nodoRegistrado.getToken() == pr.prPlus.getPr()
                || nodoRegistrado.getToken() == pr.prMinus.getPr()) {
            if (nodoRegistrado.getToken() == pr.prPlus.getPr()) {
                CasaToken(pr.prPlus.getPr());
            } else if (nodoRegistrado.getToken() == pr.prMinus.getPr()) {
                CasaToken(pr.prMinus.getPr());
            }
        }
        MetodoTeste();
        while (nodoRegistrado.getToken() == pr.prPlus.getPr()
                || nodoRegistrado.getToken() == pr.prMinus.getPr()
                || nodoRegistrado.getToken() == pr.prOu.getPr()) {
            if (nodoRegistrado.getToken() == pr.prPlus.getPr()) {
                CasaToken(pr.prPlus.getPr());
            } else if (nodoRegistrado.getToken() == pr.prMinus.getPr()) {
                CasaToken(pr.prMinus.getPr());
            } else if (nodoRegistrado.getToken() == pr.prOu.getPr()) {
                CasaToken(pr.prOu.getPr());
            }
            MetodoTeste();
        }
    }

    void MetodoTeste() throws IOException {
        MetodoF();

        while (nodoRegistrado.getToken() == pr.prMulti.getPr()
                || nodoRegistrado.getToken() == pr.prDivide.getPr()
                || nodoRegistrado.getToken() == pr.prE.getPr()) {

            if (nodoRegistrado.getToken() == pr.prMulti.getPr()
                    || nodoRegistrado.getToken() == pr.prDivide.getPr()
                    || nodoRegistrado.getToken() == pr.prE.getPr()) {
                if (nodoRegistrado.getToken() == pr.prMulti.getPr()) { // *
                    CasaToken(pr.prMulti.getPr());
                } else if (nodoRegistrado.getToken() == pr.prDivide.getPr()) {// /
                    CasaToken(pr.prDivide.getPr());
                } else {
                    if (nodoRegistrado.getToken() == pr.prE.getPr()) // or
                    {
                        CasaToken(pr.prE.getPr());
                    }
                }
                MetodoF();
            }
        }
    }

    void MetodoF() throws IOException {

        if (nodoRegistrado.getToken() == pr.prID.getPr()) { // id

            nodoAuxiliar = lexico.metodo.pesquisa(nodoRegistrado.getLexema().toLowerCase());
            nodoAuxiliar = lexico.metodo.verificaTipo(nodoAuxiliar);
            if (nodoAuxiliar.getTipo().equals(TiposSemanticos.Real.getTipo())) {
                nodoFatorTemp.setTipo(TiposSemanticos.Real.getTipo());
                lexico.metodo.defineTipo(nodoFatorTemp);
            } else if (nodoAuxiliar.getTipo().equals(TiposSemanticos.Inteiro.getTipo())) {
                nodoFatorTemp.setTipo(TiposSemanticos.Inteiro.getTipo());
                lexico.metodo.defineTipo(nodoFatorTemp);
            } else {
                lexico.mensagemErro(CodigoErros.tiposIncompativeis.getCodigoErro(), nodoAuxiliar.getLexema());
            }

            boolean isConstOuVar = false;

            if (!escopoDVar.contains(nodoAuxiliar.getLexema().toLowerCase())) {
                isConstOuVar = false;
            } else {
                isConstOuVar = true;
            }


            if (!escopoDConst.contains(nodoAuxiliar.getLexema().toLowerCase()) && isConstOuVar == false) {
                isConstOuVar = false;
            } else {
                isConstOuVar = true;
            }

            if (isConstOuVar == false) {
                lexico.mensagemErro(CodigoErros.identificadorNaoDeclarado.getCodigoErro(), nodoAuxiliar.getLexema());

            } else {
                CasaToken(pr.prID.getPr());

            }

        } else if (nodoRegistrado.getToken() == pr.prNao.getPr()) { // not
            CasaToken(pr.prNao.getPr());
            MetodoF();
        } else if (nodoRegistrado.getToken() == pr.prOpar.getPr()) { // (
            CasaToken(pr.prOpar.getPr());
            MetodoEXP();
            CasaToken(pr.prCpar.getPr());
        } else {
            MetodoV();
        }
    }

    void MetodoV() throws IOException {
        if (nodoRegistrado.getToken() == pr.prMinus.getPr()) { // -
            CasaToken(pr.prMinus.getPr());
        } else {
            nodoAuxiliar = lexico.metodo.pesquisa(nodoRegistrado.getLexema().toLowerCase());
            nodoAuxiliar = lexico.metodo.verificaTipo(nodoAuxiliar);

            if (nodoAuxiliar.getTipo().equals(TiposSemanticos.Real.getTipo())) {
                nodoFatorTemp.setTipo(TiposSemanticos.Real.getTipo());
                lexico.metodo.defineTipo(nodoFatorTemp);
            } else if (nodoAuxiliar.getTipo().equals(TiposSemanticos.Inteiro.getTipo())) {
                nodoFatorTemp.setTipo(TiposSemanticos.Inteiro.getTipo());
                lexico.metodo.defineTipo(nodoFatorTemp);
            } else {
                lexico.mensagemErro(CodigoErros.tiposIncompativeis.getCodigoErro(), nodoFatorTemp.getLexema());
            }


            CasaToken(pr.prConst.getPr());



        }

    }
}
